export const forEach = (arr, fn) => {
    if (!arr.length || !fn) return;
    let i = -1;
    let len = arr.length;
    while (++i < len) {
        let item = arr[i];
        fn(item, i, arr);
    }
};

/**
 * @param {Array} arr1
 * @param {Array} arr2
 * @description 得到两个数组的交集, 两个数组的元素为数值或字符串
 */
export const getIntersection = (arr1, arr2) => {
    let len = Math.min(arr1.length, arr2.length);
    let i = -1;
    let res = [];
    while (++i < len) {
        const item = arr2[i];
        if (arr1.indexOf(item) > -1) res.push(item);
    }
    return res;
};

/**
 * @param {Array} arr1
 * @param {Array} arr2
 * @description 得到两个数组的并集, 两个数组的元素为数值或字符串
 */
export const getUnion = (arr1, arr2) => {
    return Array.from(new Set([...arr1, ...arr2]));
};

/**
 * @param {Array} target 目标数组
 * @param {Array} arr 需要查询的数组
 * @description 判断要查询的数组是否至少有一个元素包含在目标数组中
 */
export const hasOneOf = (target, arr) => {
    return target.some(_ => arr.indexOf(_) > -1);
};

/**
 * @param {String|Number} value 要验证的字符串或数值
 * @param {*} validList 用来验证的列表
 */
export function oneOf(value, validList) {
    for (let i = 0; i < validList.length; i++) {
        if (value === validList[i]) {
            return true;
        }
    }
    return false;
}

/**
 * @param {Number} timeStamp 判断时间戳格式是否是毫秒
 * @returns {Boolean}
 */
const isMillisecond = timeStamp => {
    const timeStr = String(timeStamp);
    return timeStr.length > 10;
};

/**
 * @param {Number} timeStamp 传入的时间戳
 * @param {Number} currentTime 当前时间时间戳
 * @returns {Boolean} 传入的时间戳是否早于当前时间戳
 */
const isEarly = (timeStamp, currentTime) => {
    return timeStamp < currentTime;
};

/**
 * @param {Number} num 数值
 * @returns {String} 处理后的字符串
 * @description 如果传入的数值小于10，即位数只有1位，则在前面补充0
 */
const getHandledValue = num => {
    return num < 10 ? '0' + num : num;
};

/**
 * @param {Number} timeStamp 传入的时间戳
 * @param {Number} startType 要返回的时间字符串的格式类型，传入'year'则返回年开头的完整时间
 */
const getDate = (timeStamp, startType) => {
    const d = new Date(timeStamp * 1000);
    const year = d.getFullYear();
    const month = getHandledValue(d.getMonth() + 1);
    const date = getHandledValue(d.getDate());
    const hours = getHandledValue(d.getHours());
    const minutes = getHandledValue(d.getMinutes());
    const second = getHandledValue(d.getSeconds());
    let resStr = '';
    if (startType === 'year') resStr = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + second;
    else resStr = month + '-' + date + ' ' + hours + ':' + minutes;
    return resStr;
};

/**
 * @param {String|Number} timeStamp 时间戳
 * @returns {String} 相对时间字符串
 */
export const getRelativeTime = timeStamp => {
    // 判断当前传入的时间戳是秒格式还是毫秒
    const IS_MILLISECOND = isMillisecond(timeStamp);
    // 如果是毫秒格式则转为秒格式
    if (IS_MILLISECOND) Math.floor(timeStamp /= 1000);
    // 传入的时间戳可以是数值或字符串类型，这里统一转为数值类型
    timeStamp = Number(timeStamp);
    // 获取当前时间时间戳
    const currentTime = Math.floor(Date.parse(new Date()) / 1000);
    // 判断传入时间戳是否早于当前时间戳
    const IS_EARLY = isEarly(timeStamp, currentTime);
    // 获取两个时间戳差值
    let diff = currentTime - timeStamp;
    // 如果IS_EARLY为false则差值取反
    if (!IS_EARLY) diff = -diff;
    let resStr = '';
    const dirStr = IS_EARLY ? '前' : '后';
    // 少于等于59秒
    if (diff <= 59) resStr = diff + '秒' + dirStr;
    // 多于59秒，少于等于59分钟59秒
    else if (diff > 59 && diff <= 3599) resStr = Math.floor(diff / 60) + '分钟' + dirStr;
    // 多于59分钟59秒，少于等于23小时59分钟59秒
    else if (diff > 3599 && diff <= 86399) resStr = Math.floor(diff / 3600) + '小时' + dirStr;
    // 多于23小时59分钟59秒，少于等于29天59分钟59秒
    else if (diff > 86399 && diff <= 2623859) resStr = Math.floor(diff / 86400) + '天' + dirStr;
    // 多于29天59分钟59秒，少于364天23小时59分钟59秒，且传入的时间戳早于当前
    else if (diff > 2623859 && diff <= 31567859 && IS_EARLY) resStr = getDate(timeStamp);
    else resStr = getDate(timeStamp, 'year');
    return resStr;
};

/**
 * @returns {String} 当前浏览器名称
 */
export const getExplorer = () => {
    const ua = window.navigator.userAgent;
    const isExplorer = (exp) => {
        return ua.indexOf(exp) > -1;
    };
    if (isExplorer('MSIE')) return 'IE';
    else if (isExplorer('Firefox')) return 'Firefox';
    else if (isExplorer('Chrome')) return 'Chrome';
    else if (isExplorer('Opera')) return 'Opera';
    else if (isExplorer('Safari')) return 'Safari';
};

/**
 * @description 绑定事件 on(element, event, handler)
 */
export const on = (function () {
    if (document.addEventListener) {
        return function (element, event, handler) {
            if (element && event && handler) {
                element.addEventListener(event, handler, false);
            }
        };
    } else {
        return function (element, event, handler) {
            if (element && event && handler) {
                element.attachEvent('on' + event, handler);
            }
        };
    }
})();

/**
 * @description 解绑事件 off(element, event, handler)
 */
export const off = (function () {
    if (document.removeEventListener) {
        return function (element, event, handler) {
            if (element && event) {
                element.removeEventListener(event, handler, false);
            }
        };
    } else {
        return function (element, event, handler) {
            if (element && event) {
                element.detachEvent('on' + event, handler);
            }
        };
    }
})();

export function formatDate(str, fmt) {
    if (str == '0001-01-01T00:00:00Z' || str == '0001-01-01T00:00:00') return '';
    if (str == null || str == undefined || str == '' || str == 'null') {
        return '';
    }
    var date = new Date(str);
    let o = {
        'M+': date.getMonth() + 1,                 //月份
        'd+': date.getDate(),                    //日
        'h+': date.getHours(),                   //小时
        'm+': date.getMinutes(),                 //分
        's+': date.getSeconds(),                 //秒
        'q+': Math.floor((date.getMonth() + 3) / 3), //季度
        'S': date.getMilliseconds()             //毫秒
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp('(' + k + ')').test(fmt))
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
    return fmt;
};

const mvcParamMatch = (function () {

    let MvcParameterAdaptive = {};
    //验证是否为数组
    MvcParameterAdaptive.isArray = Function.isArray || function (o) {
        return typeof o === 'object' &&
            Object.prototype.toString.call(o) === '[object Array]';
    };

    //将数组转换为对象
    MvcParameterAdaptive.convertArrayToObject = function (arrName, array, saveOjb) {
        var obj = saveOjb || {};

        function func(name, arr) {
            for (var i in arr) {
                if (!MvcParameterAdaptive.isArray(arr[i]) && typeof arr[i] === 'object') {
                    for (var j in arr[i]) {
                        if (MvcParameterAdaptive.isArray(arr[i][j])) {
                            func(name + '[' + i + '].' + j, arr[i][j]);
                        } else if (typeof arr[i][j] === 'object') {
                            MvcParameterAdaptive.convertObject(name + '[' + i + '].' + j + '.', arr[i][j], obj);
                        } else {
                            obj[name + '[' + i + '].' + j] = arr[i][j];
                        }
                    }
                } else {
                    obj[name + '[' + i + ']'] = arr[i];
                }
            }
        }

        func(arrName, array);

        return obj;
    };

    //转换对象
    MvcParameterAdaptive.convertObject = function (objName, turnObj, saveOjb) {
        var obj = saveOjb || {};

        function func(name, tobj) {
            for (var i in tobj) {
                if (MvcParameterAdaptive.isArray(tobj[i])) {
                    MvcParameterAdaptive.convertArrayToObject(i, tobj[i], obj);
                } else if (typeof tobj[i] === 'object') {
                    func(name + i + '.', tobj[i]);
                } else {
                    obj[name + i] = tobj[i];
                }
            }
        }

        func(objName, turnObj);
        return obj;
    };

    return function (json, arrName) {
        arrName = arrName || '';
        if (typeof json !== 'object') return {};
        if (MvcParameterAdaptive.isArray(json)) return json;
        // if (MvcParameterAdaptive.isArray(json) && !arrName) throw new Error('请指定数组名，对应Action中数组参数名称！');
        //
        // if (MvcParameterAdaptive.isArray(json)) {
        //     return MvcParameterAdaptive.convertArrayToObject(arrName, json);
        // }
        return MvcParameterAdaptive.convertObject('', json);
    };
})();

/**
 * 请求参数的格式化
 */
export const paramMatch = mvcParamMatch;

export const getDateTimeIntervalMinute = (startTime, endTime) => {
    let stime = Date.parse(new Date(startTime));
    let etime = Date.parse(new Date(endTime));
    let usedTime = etime - stime;  //两个时间戳相差的毫秒数
    let second = Math.floor(usedTime / 1000); //秒数
    let minutes = second / 60; //分钟数
    return minutes;

    // let days = Math.floor(usedTime / (24 * 3600 * 1000));
    // //计算出小时数
    // let leave1 = usedTime % (24 * 3600 * 1000);    //计算天数后剩余的毫秒数
    // let hours = Math.floor(leave1 / (3600 * 1000));
    // //计算相差分钟数
    // let leave2 = leave1 % (3600 * 1000);        //计算小时数后剩余的毫秒数
    // let minutes = Math.floor(leave2 / (60 * 1000));
    // let time = days + '天' + hours + '时' + minutes + '分';
    // // return time;
    // return minutes;
};



